/**
 * 
 */
package edu.caltech.android.database;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import android.os.Environment;
import android.util.Log;
import edu.caltech.android.sensor.accel.AccelSample;

/**
 * Manage writing and reading measurement files to external storage (SD card).
 * NOTE: external storage can be viewed and modified by users, other apps, etc.
 * 
 * TODO this dumps (potentially lots of) files into the root directory. Sloppy.
 * Possible directories to use instead: Context.getExternalFilesDir
 * 
 * TODO reading and writing probably won't work if the user has mounted their SD
 * card to their desktop, e.g. "USB Storage" is on. One possible check for this
 * is String state = Environment.getExternalStorageState(); which is normally
 * "mounted" but becomes "shared" when USB storage is on.
 * 
 * 
 * @author mfaulk
 * 
 */
public class ExternalStorageManager {
	private static final String TAG = "ExternalStorageManager";
	public static final String fileExtension = "mea";

	/**
	 * Serialize samples and write to a file in persistent storage. The UTC
	 * timestamp of the first sample is appended to a generic file name. If the
	 * ArrayList is empty, the timestamp will be 0
	 * 
	 * TODO: ArrayList<AccelSample> probably isn't the best thing to write out
	 * to file. It would be good to record some representative position data as
	 * well.
	 * 
	 * @param samples
	 * @return the name of the file the samples were written to
	 * @throws IOException
	 */
	public static String writeLogfile(ArrayList<AccelSample> samples)
			throws IOException {
		// NumberFormat formatter = new DecimalFormat("0000");
		// String number = formatter.format(nextFileIndex);
		long timeStamp = 0L;

		if (!samples.isEmpty()) {
			timeStamp = samples.get(0).t;
		}

		String fileName = "accel_" + Long.toString(timeStamp) + "."
				+ fileExtension;
		Log.v(TAG, "writing " + fileName);
		FileOutputStream fos = null;
		ObjectOutputStream out = null;

		File root = Environment.getExternalStorageDirectory();
		if (root.canWrite()) {
			File measurementFile = new File(root, fileName);
			fos = new FileOutputStream(measurementFile);
			out = new ObjectOutputStream(fos);
			out.writeObject(samples);
			out.close();
			fos.close();
		} else {
			Log.v(TAG, "Can't write logfile. Is USB storage on?");
		}
		return fileName;
	}

	/**
	 * 
	 * @param fileName
	 * @return
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	@SuppressWarnings("unchecked")
	public static ArrayList<AccelSample> readLogFile(String fileName)
			throws IOException, ClassNotFoundException {
		ArrayList<AccelSample> samples = null;
		FileInputStream fis = null;
		ObjectInputStream in = null;

		fis = new FileInputStream(fileName);
		in = new ObjectInputStream(fis);
		// this is an unchecked cast. Can't be helped...
		samples = (ArrayList<AccelSample>) in.readObject();
		in.close();
		return samples;
	}

	/**
	 * 
	 * @param fileName
	 *            Path to a measurement file. Must have correct file extension
	 * @return
	 */
	public static boolean deleteLogFile(String fileName) {
		boolean deleted = false;
		if (fileName.endsWith(fileExtension)) {
			File root = Environment.getExternalStorageDirectory();
			if (root.canWrite()) {

				File file = new File(root, fileName);
				if (file.exists()) {
					deleted = file.delete();
				} else {
					Log
							.v(TAG, fileName
									+ " does not exist? Is USB storage on?");
				}
			}
		} else {
			Log.v(TAG, "root cannot write");
		}

		return deleted;
	}

	// Sample code for an activity or service to monitor the state of external
	// storage
	//
	// BroadcastReceiver mExternalStorageReceiver;
	// boolean mExternalStorageAvailable = false;
	// boolean mExternalStorageWriteable = false;
	//
	// void updateExternalStorageState() {
	// String state = Environment.getExternalStorageState();
	// if (Environment.MEDIA_MOUNTED.equals(state)) {
	// mExternalStorageAvailable = mExternalStorageWriteable = true;
	// } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
	// mExternalStorageAvailable = true;
	// mExternalStorageWriteable = false;
	// } else {
	// mExternalStorageAvailable = mExternalStorageWriteable = false;
	// }
	// handleExternalStorageState(mExternalStorageAvailable,
	// mExternalStorageWriteable);
	// }
	//
	// void startWatchingExternalStorage() {
	// mExternalStorageReceiver = new BroadcastReceiver() {
	// @Override
	// public void onReceive(Context context, Intent intent) {
	// Log.i("test", "Storage: " + intent.getData());
	// updateExternalStorageState();
	// }
	// };
	// IntentFilter filter = new IntentFilter();
	// filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
	// filter.addAction(Intent.ACTION_MEDIA_REMOVED);
	// registerReceiver(mExternalStorageReceiver, filter);
	// updateExternalStorageState();
	// }
	//
	// void stopWatchingExternalStorage() {
	// unregisterReceiver(mExternalStorageReceiver);
	// }
	//	

}
